<?php
	class EventsController extends AppController {
		/*
		 * Attributes
		 */
        var $name = 'Events';
		var $uses = array('Event', 'Picture', 'Family');
		
		/*
		 * Methods
		 */

		/*
		 * Returns true if the logged in user is authorized
		 *
		 */
		function isAuthorized() {
		    $this->loadModel('Person');
            $uid = $this->Auth->user('id');

		    if ($this->action == "view") {
		        $params = $this->extractNamedParams(array('event'));
		        $evid = $params['event'];
		        if (!$evid || !$this->Person->canViewEvent($uid, $evid)) {
	                $this->Session->setFlash("You cannot access that location");
		            return false;
		        } else {
		            return true;
		        }
		    } else if ($this->action == "delete") {
		        $evid = $this->params['pass'][0];

		        if ($this->Person->isEventAdmin($uid, $evid)) {
		            return true;
		        } else {
		            $this->Session->setFlash("You cannot edit this event");
		    	    return false;
		        }
		    }

		    return true;
		}

		/*
		 * Deletes an event by ID and all the photos in it
		 *
		 */
		function delete($evid) {
			$this->loadModel('Picture');

			$event = $this->Event->getEventFromID($evid);
			$this->Session->setFlash("Event {$event['name']} deleted");

			$this->Picture->deleteAll(array('Picture.event_id' => $evid));
			$this->Event->deleteAll(array('Event.id' => $evid));

			// Delete the folder from the filesystem
			$event_folder = WWW_ROOT . 'pix' . DS . $evid;
			$this->Event->rrmdir($event_folder);

            $this->redirect($this->referer());
        }

		/*
		
		/*
		 * Deletes all photos in an event while keeping the event album
		 *
		 */
		function deleteAllPhotos($evid) {
			$this->loadModel('Picture');
			$event = $this->Event->getEventFromID($evid);
			$this->Session->setFlash("All photos in {$event['name']} deleted");
			$this->Picture->deleteAll(array('Picture.event_id' => $evid));
			$this->redirect($this->referer());
		}


		/*
		 * Called when no action is passed to this controller
		 * Display all the events or search results if namedParam 'query' is passed to it
		 * 
		 *
		 */
		function index() {
            $this->loadModel('Family');
            $this->loadModel('Person');
            $this->loadModel('Picture');
			$username = $this->Auth->user('username');


			//////////
			// Redirection stuff for sort/search
			//////////

			// if search bar gets something, redirect to /events/index/query:something
			if ($this->data != null && array_key_exists('query', $this->data['Event'])) {
				$this->redirect(array_merge($this->params['named'], array('controller' => 'events', 'action' => 'index', 'query' => $this->data['Event']['query'])));
				return; // to avoid loading the page twice after returning from redirection
			}

			// If we get a query type posted, redirect to /events/index/sort:something
			if ($this->data != null && array_key_exists('sort_type', $this->data['Event'])) {
			    $this->redirect(array_merge($this->params['named'], array('controller' => 'events', 'action' => 'index', 'sort' => $this->data['Event']['sort_type'])));
			    return;
			}


			// if named param 'query' has something, do a search; otherwise display all
			$params = $this->params['named'];
			$hasFilter = false;
			if (array_key_exists("query", $params)) {
				$hasFilter = true;
				$searchterm = $params['query'];
			}

			// Set the value of sort type based upon input
			if (array_key_exists('sort', $params)) {
			    $sort_type = $params['sort'];
			} else {
			    $sort_type = 'oldest';
			}

			$this->data['Event']['sort_type'] = $sort_type;


            $fams = $this->Person->getFamiliesFromPerson($this->Auth->user('id'));

            // Send user to a welcome page if they don't have a family yet
            if (empty($fams)) {
                $this->redirect(array('controller' => 'people', 'action' => 'welcome'));
            }

            //////////
            // Figure out sort method (if any)
            //////////

            if ($sort_type == 'newest') {
                $sort_array = 'Event.id DESC';
            } else if ($sort_type == 'datedesc') {
                $sort_array = 'Event.eventdate DESC';
            } else if ($sort_type == 'dateasc') {
                $sort_array = 'Event.eventdate ASC';
            } else {
                $sort_array = 'Event.id ASC';
            }
            // Default search will be date added ascending (oldest first)



            $famArray = array();
            $thumArray = array();
            $eventAdminFlag = array();
            foreach($fams as $family) {
                
                $events = $this->Family->getEventsFromFamilies(array($family));
				$family['is_admin'] = $this->Family->isPersonFamilyAdmin($this->Auth->user('id'), $family['id']);
                foreach($events as $event){
                	$eventAdminFlag[$event] = $this->Person->isEventAdmin($this->Auth->user('id'), $event);
                }

				if ($hasFilter) {
					$familyEvents = $this->Event->find('all', array('conditions' => array('Event.id' => $events, 'Event.Name LIKE' => "%".$searchterm."%"), 'order' => $sort_array));
				} else {
					$familyEvents = $this->Event->find('all', array('conditions' => array('Event.id' => $events), 'order' => $sort_array));
				}
                foreach($events as $evid) {
                    $thumArray[$evid] = $this->Picture->getThumbsByEID($evid);
                }

				// Adding one key-value entry to each event ('count' => # of pix)
				for ($i = 0; $i < count($familyEvents); $i++) {
					$picArray = $this->Picture->getPicturesFromEvent($familyEvents[$i]['Event']['id']);
					$picCount = count($picArray);
					$familyEvents[$i]['Event']['count'] = $picCount;
				}
                $famArray[] = array('Family' => $family, 'Events' => $familyEvents);
            }

            $this->set('famArray', $famArray);
            $this->set('thumarr', $thumArray);
			$this->set('hasFilter', $hasFilter);
			$this->set('currentUser', $username);
			$this->set('eventsAdminFlags', $eventAdminFlag);
		}

		/*
		 * This controller takes care of the event display (4 pictures per page)
		 *
		 *
		 */ 
        function view() {
            // If we get data in the sort field, redirect to the proper location
            if (!empty($this->data)) {
                if (array_key_exists('sort_type', $this->data['Event'])) {
                    $sort =  $this->data['Event']['sort_type'];
                    $this->redirect(array_merge($this->params['named'], array('controller' => 'events', 'action' => 'view', 'sort' => $sort)));
                } else if (array_key_exists('page_select', $this->data['Event'])) {
                    $page = $this->data['Event']['page_select'];
                    $this->redirect(array_merge($this->params['named'], array('controller' => 'events', 'action' => 'view', 'page' => $page)));
                }
            }



            // Get the parameters we will need
            $passed = $this->params['named'];
            $params = $this->extractnamedParams(array('event'),
                                                array('sort' => false, 'page' => false));


            if (!$params) {
                // Required parameters were not present (Namely event number)
                $this->Session->setFlash("Invalid event query");
                $this->redirect('/events');
            }

            // Set the default sort type
            $sortArray = array('Picture.id ASC');
            $this->data['Event']['sort_type'] = 'oldest';

            // If we do get passed in a sort type, set it appropriately
            if ($params['sort']) {
                $sort = $params['sort'];

                if ($sort == 'oldest') {
                    $sortArray = array('Picture.id ASC');
                    $this->data['Event']['sort_type'] = 'oldest';
                } else if ($sort == 'newest') {
                    $sortArray = array ('Picture.id DESC');
                    $this->data['Event']['sort_type'] = 'newest';
                }
            }

            // Set page if present, default if not
            if (!array_key_exists('page', $this->params['named'])) {
                $page = 1;
            } else {
                $page = $this->params['named']['page'];
            }

            $this->data['Event']['page_select'] = $page;

            $id = $params['event'];

            // Default to 4 pictures on each view page
			$picturesPerPage = 4;

            // Set some easy variables
            $this->loadModel('Picture');
            $this->set('pageno', $page);
            $this->set('eventno', $id);
            $this->set('event', $this->Event->getEventFromID($id));

            // Set a flag stating whether the current user is an admin of this event
            $this->set('admin_flag', $this->Family->isPersonFamilyAdmin($this->Auth->user('id'), $this->Event->getHostFromID($id)));

	    // Set a var for the list of family names associated with this event
	    $this->set('family_names', $this->Event->getEventFamilyNames($id));

            // We need to get the pictures for the given page
            $pictures = $this->Picture->getPicturesFromEvent($id, $sortArray);
            $numPictures = count($pictures);
            if ($numPictures == 0) {
                $lastPage = 1;
            } else {
                $lastPage = ceil($numPictures / $picturesPerPage);
            }

            // Set the next and previous page numbers
            $this->set('nextPage', $this->Event->getNextPage($numPictures, $page, $picturesPerPage));
            $this->set('previousPage', $this->Event->getPreviousPage($numPictures, $page, $picturesPerPage));

            if ($page < 1) {
                $this->redirect(array_merge($this->params['named'], array('controller' => 'events', 'action' => 'view', 'page' => '1')));
            }

            if ($page > $lastPage) {
                $this->redirect(array_merge($this->params['named'], array('controller' => 'events', 'action' => 'view', 'page' => $lastPage)));
            }

            // Now, we figure out what part of the sub array to return for pictures to display
            $firstPicture = $page * $picturesPerPage - $picturesPerPage; // Make sure to account for 1 indexed pages
            $lastPicture = $firstPicture + $picturesPerPage;


            $numpages = ceil(count($pictures) / $picturesPerPage);
            $pageArray = array();

            for ($i = 1; $i <= $numpages; $i++) {
                $pageArray[$i] = $i;
            }



            $this->set('numpages', $numpages);
            $this->set('pageList', $pageArray);

            // Get only the pictures we want to display (So the view doesn't have to know
            // what to display)
            $pictures = array_slice($pictures,$firstPicture,$picturesPerPage);
            foreach($pictures as $key => $val){
                $temp = $val;
                $temp['is_owner'] = $this->Picture->userOwnsPicture($val['id'], $this->Auth->user('id'));
                $pictures[$key] = $temp;
            }
            $this->set('pictures', $pictures);

        }

		/*
        /*
	 * The action for event creation
	 *
	 */
	function create(){
        	$this->loadModel('Person');

			if(!empty($this->data)){
				$this->data['Event']['family_id'] = $this->data['Family']['Family'];
				
				if($this->Event->save($this->data)){
					$this->Session->setFlash('Event ' . $this->data['Event']['name'] . ' successfully created.');
					//$this->redirect('/events/index');
					$this->redirect(array('controller' => 'events', 'action' => 'view', 'event' => $this->Event->id));
				}else{
					$this->Session->setFlash('Event was not created, please try again. ');
				}
			}
			$fams = $this->Person->getFamiliesFromPerson($this->Auth->user('id'));

			$fidlist = array();
			foreach($fams as $fam) {
			    $fidlist[] = $fam['id'];
			}

			$families = $this->Event->Family->find('list', array('conditions' => array('Family.id' => $fidlist)));
        	$this->set(compact('families'));

        	if (array_key_exists('family', $this->params['named'])) {
        	    $fam = $this->params['named']['family'];

        	    $this->data['Family']['Family'] = $fam;
        	}
		}


	/*
	 * Invoke a media view to send archived event photos to the browser as binary content
	 *
	 */
		function download($eid = NULL) {

			$this->loadModel('Family');
			$this->loadModel('Person');

			$pid = $this->Auth->user('id');
			if (!$this->Person->canViewEvent($pid, $eid)) {
				//redirect to event index when user attemps to use url to
					//download events not viewable to them
				$this->redirect(array('controller' => 'events', 'action' => 'index'));
			}

			$event = $this->Event->getEventFromID($eid);
			$eventName = str_replace(' ', '_', $event['name']);
			$eventPath = '.' . DS . 'pix' . DS . $eid;
			$tmpPath = '..' . DS . 'tmp' . DS;
			$archiveName = 'archived_event_' . $eid;
			$archivePath = $tmpPath . $archiveName;

			if (file_exists($eventPath)) {

			  $zip = new ZipArchive;
			  $result = $zip->open($archivePath, ZipArchive::CREATE);

			  if ($result === TRUE) {
			    $files = glob($eventPath . DS . '*');
			    $count = 0;
			    $digits = strlen(count($files));
			    foreach ($files as $file) {
			      $ext = end(explode('.', $file));
			      $paddedCount = str_pad($count, $digits, '0', STR_PAD_LEFT);
			      $zip->addFile($file, $eventName . '_' . $paddedCount . '.' . $ext);
			      $count = $count + 1;
			    }
			    $zip->close();
			  }

			  // Send the binary content (archive) to the user
			  $this->view = 'Media';
			  $params = array(
					  'id'=> $archiveName,
					  'name'=> $eventName,
					  'download'=> true,
					  'extension' => 'zip',
					  'path'=> $tmpPath
					  );
			  $this->set($params);
			} else {
			  $this->Session->setFlash('There\'s no photo to download!');
			  $this->redirect($this->referer());
			}

			
			  // Clean the expired archives in tmp folder
			  

			  $expireTimeSeconds = 10;
			  $fileNames = 'archived_event_*';
			  foreach (glob($tmpPath.$fileNames) as $file) {
			  $timeModified = filemtime($file);
			  $fileAge = time() - $timeModified;
			  if ($fileAge > ($expireTimeSeconds) && $file != $archivePath) {
			  unlink($file);
			  }
			  }
			
		}

		function share() {
			$this->loadModel('Family');

            // Get the parameters we will need
            $passed = $this->params['named'];
            $params = $this->extractnamedParams(array('event'),
                                                array('sort' => false, 'page' => false));
            if (!$params) {
                // Required parameters were not present (Namely event number)
                $this->Session->setFlash("Cannot share an event without providing an event id");
                $this->redirect('/events');
            }

            $event = $this->Event->getEventFromID($params['event']);

                        $this->set('event', $event);

			//$family_names = $this->Event->getEventFamilyNames($params['event']);
			//$family_ids = $this->Event->getEventFamilyIDs($params['event']);

			$event_family_host_id = $this->Event->getHostFromID($params['event']);
			$event_family_host = $this->Family->getFamilyFromID($event_family_host_id);
			$this->set('familyHost', $event_family_host);

			//$families_sharing_event_ids = $this->Event->EventsFamily->find('list', array('conditions' => array('EventsFamily.event_id' => $params['event']),
			//																		'fields' => array('EventsFamily.family_id')));

			$families_sharing_event = $this->Family->getFamilyNames($this->Family->getFamiliesSharingEvent($params['event']));

			//$families_sharing_event = $this->Family->getFamilyNames($families_sharing_event_ids);
			$this->set('familiesSharingEvent', $families_sharing_event);

			$all_families = $this->Family->getAllFamilies();
			$this->set('all_families', $all_families);
		}

		//
		function updatesharing() {
			$this->autoRender = false;
			//$this->loadModel('Family');

			// Get the parameters we will need
            $passed = $this->params['named'];
            $params = $this->extractnamedParams(array('event'),
                                                array('sort' => false, 'page' => false));

			// TODO: verify that the user has access to change sharing for the passed in event id


            if (!$params) {
                // Required parameters were not present (Namely event number)
                $this->Session->setFlash("Cannot update sharing for an event without specifiyng an event id");
                $this->redirect('/events');
            }


			$event = $this->Event->getEventFromID($params['event']);

			$event_family_host_id = $this->Event->getHostFromID($params['event']);
			//$event_family_host = $this->Family->getFamilyFromID($event_family_host_id);

			// this includes the event host
			$families_sharing_event = $this->Family->getFamilyNames($this->Family->getFamiliesSharingEvent($params['event']));

			//debug($this->params, true);

			if(!empty($this->params['form'])){

				// check for new families added to this event
				foreach ($this->params['form'] as $post_family_name => $post_family_id) {
					// is current family not sharing this event?  if so, add it to this event
					if (!array_key_exists($post_family_id, $families_sharing_event)) {
						if ($post_family_id == $event_family_host_id) {
							// we should never get here
							debug($post_family_id);
							exit();
						}
						$this->Event->EventsFamily->create($data);
						$data['EventsFamily'] = array();
						$data['EventsFamily']['event_id'] = $params['event'];
						$data['EventsFamily']['family_id'] = $post_family_id;
											
						//debug("save array: ");
                        //debug($data, true);

						if ($this->Event->EventsFamily->save($data)) {
                                //debug("association was saved");
                        }       
                        else {
                                //debug("association could not be saved");
                        }

						unset($data);
					}
				}


				//$this->Session->setFlash("success updating non empty post");

				//$this->render('updatesharing', 'ajax');

				//$families = split(',', $this->data['families']);
				//$this->Session->setFlash($this->data['families']);
			}
			else {
				// if we get here then we need to remove all the sharing for this event
				//debug($this->params['form'], true);
				//$this->Session->setFlash("emtpy post");

				//	$this->Events->EventsFamily->delete($fid
			}

			// check for families that no longer share this event
			foreach ($families_sharing_event as $family_id => $family_name) {
				// if a family that is currently sharing this event is not present
				// in the update request, remove the sharing for this event for this family
				// of course, ignore the family that hosts the event; we cannot remove that family from
				// sharing this event, since the host family owns the event
				if (!in_array($family_id, $this->params['form']) && ($family_id != $event_family_host_id)) {
					// find the id in the EventsFamily table that corresponds to the current
					// family and event
					$record_to_remove = $this->Event->EventsFamily->find('first', array('conditions' =>
										array('event_id' => $params['event'],
											  'family_id' => $family_id)));
					//debug($record_to_remove, true);
					$this->Event->EventsFamily->delete($record_to_remove['EventsFamily']['id'], false);
				}
			}

			$this->Session->setFlash("Event {$event['name']} was succesfully shared");
			$this->redirect('/events');
		}


	}
?>
